package cn.itsource.user.service.impl;

import cn.itsource.basic.constant.PetHomeConstant;
import cn.itsource.basic.constant.VerificationConstant;
import cn.itsource.basic.exception.CustomException;
import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.basic.util.HttpClientUtils;
import cn.itsource.user.constant.WechatConstant;
import cn.itsource.user.domain.LoginInfo;
import cn.itsource.user.domain.User;
import cn.itsource.user.domain.WechatUser;
import cn.itsource.user.dto.UserDto;
import cn.itsource.user.mapper.LogininfoMapper;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.user.mapper.WechatUserMapper;
import cn.itsource.user.service.IWechatService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import jdk.nashorn.internal.runtime.regexp.JoniRegExp;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class WechatServiceImpl extends BaseServiceImpl<WechatUser> implements IWechatService {
    @Autowired
    private WechatUserMapper wechatUserMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public Map<String,Object> handleCallBackMethod(Map<String, String> map) {
        //获取授权码
        String code = map.get("code");
        //获取token的url地址
        String tokenUrl = WechatConstant.TOKEN_URL.replace("APPID", WechatConstant.APPID)
                .replace("SECRET", WechatConstant.SECRET)
                .replace("CODE", code);
        //获取token的json字符串
        String tokenJsonStr = HttpClientUtils.httpGet(tokenUrl);
        //把json字符串转为json对象
        JSONObject jsonObject = JSON.parseObject(tokenJsonStr);
        //获取json对象中指定的值（openid是微信用户唯一标志）
        String openid = jsonObject.getString("openid");
        //token的值
        String access_token = jsonObject.getString("access_token");
        System.out.println(openid+"          "+access_token);
        //获取用户的url地址
        String userUrl = WechatConstant.USER_URL.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid);
        //获取json字符串
        String userJsonStr = HttpClientUtils.httpGet(userUrl);
        //把json字符串转为json对象（获取用户json对象）
        jsonObject = JSON.parseObject(userJsonStr);
        //通过openid查询微信用户对象
        WechatUser wechatUser = wechatUserMapper.loadByOpenid(openid);
        //定义一个map集合，向门户网站响应后台数据
        Map<String, Object> resultMap = new HashMap<>();
        if(wechatUser == null){
            wechatUser = new WechatUser();
            wechatUser.setOpenid(openid);
            //昵称
            wechatUser.setNickname(jsonObject.getString("nickname"));
            //性别
            wechatUser.setSex(jsonObject.getInteger("sex"));
            //地址
            wechatUser.setAddress(jsonObject.getString("country")
                    +jsonObject.getString("province")
                    +jsonObject.getString("city"));
            //头像
            wechatUser.setHeadimgurl(jsonObject.getString("headimgurl"));
            //保存微信用户
            wechatUserMapper.save(wechatUser);
            //跳转到绑定界面(装openid，因为绑定账号，其实就是修改t_wxuser对应的数据)
            resultMap.put("openid", openid);//只要后端返回了openid，就意味着我要跳转到绑定界面
            return resultMap;
        }else{
            LoginInfo logininfo = wechatUser.getLogininfo();
            if (logininfo == null) {
                //跳转到绑定界面
                resultMap.put("openid", openid);
                return resultMap;
            }else{
                //直接登录(给redis设置值，给浏览器存储token和loginUser)
                String token = UUID.randomUUID().toString();
                redisTemplate.opsForValue().set(token, logininfo, 30, TimeUnit.MINUTES);
                resultMap.put("token", token);
                resultMap.put("loginUser", logininfo);
                return resultMap;
            }
        }
    }

    @Override
    public  Map<String, Object> binder(UserDto userDto) throws CustomException {
        //校验数据
        checkData(userDto);
        //通过手机号和type在t_logininfo中去查询是否有对应的数据
        LoginInfo loginInfo = logininfoMapper.loadByPhoneAndState(userDto.getPhone(), userDto.getType());
        //证明不存在
        if (loginInfo == null) {
            //创建登录信息
            loginInfo = createLoginInfo(userDto);
            //保存LoginInfo
            logininfoMapper.save(loginInfo);
            //创建用户
            User user = createUser(loginInfo);
            userMapper.save(user);
            //绑定微信
            wechatUserMapper.binderWechatAndLoginInfo(loginInfo.getId(), userDto.getOpenid());
        }else{
            //绑定微信
            wechatUserMapper.binderWechatAndLoginInfo(loginInfo.getId(), userDto.getOpenid());
        }
        //直接登录(给redis设置值，给浏览器存储token和loginUser)
        String token = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(token, loginInfo, 30, TimeUnit.MINUTES);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("token", token);
        resultMap.put("loginUser", loginInfo);
        return resultMap;
    }

    private User createUser(LoginInfo loginInfo) {
        User user = new User();
        BeanUtils.copyProperties(loginInfo, user);
        user.setLoginInfo(loginInfo);
        return user;
    }

    private LoginInfo createLoginInfo(UserDto userDto) {
        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setPhone(userDto.getPhone());
        loginInfo.setType(userDto.getType());
        return loginInfo;
    }

    private void checkData(UserDto userDto) throws CustomException {
        if(StringUtils.isEmpty(userDto.getPhone())){
            throw new CustomException("手机必填!!");
        }
        if(StringUtils.isEmpty(userDto.getCode())){
            throw new CustomException("验证码必填!!");
        }
        //89ij:3423452353535
        String codeValue = (String) redisTemplate.opsForValue().get(userDto.getPhone()
                + ":" + VerificationConstant.USER_BINDER);
        //获取redis存储的验证码
        String code = codeValue.split(":")[0];
        if(!code.equals(userDto.getCode())){
            throw new CustomException("验证码错误!!");
        }
    }
}
